package com.huawei.basic.service.impl;

import com.fasterxml.jackson.core.util.VersionUtil;
import com.huawei.basic.constant.BaseConstants;
import com.huawei.basic.dto.RegisterDto;
import com.huawei.basic.exception.BusinessException;
import com.huawei.basic.service.IVerifyCodeService;
import com.huawei.basic.utils.SmsSendUtils;
import com.huawei.basic.utils.StrUtils;
import com.huawei.basic.utils.VerifyCodeUtils;
import com.huawei.user.domain.User;
import com.huawei.user.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.concurrent.TimeUnit;

@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {
    @Autowired
    private RedisTemplate redisTemplate;
<<<<<<< HEAD
    @Autowired
    private UserMapper userMapper;

    @Override
    public String imageCode(String key) {
//   2.service层业务逻辑
//   。（我们不需要关注是第几次发送图形验证码，每次都要新的）
//   。生成验证码code=9527
        String code = StrUtils.getComplexRandomString(4);
//   。将图形验证码保存到redis 要设置过期时间 5分钟    使用前端传递的UUID随机串作为key
        redisTemplate.opsForValue().set(
                key,//key
                code,//验证码
                5,//过期时间
                TimeUnit.MINUTES);//过期时间的单位
//   。使用JDK自带的2D引擎把code画成图
//   。使用Base64编码引擎，把图片编码成字符串
//   。返回字符串给前端
        return VerifyCodeUtils.VerifyCode(98, 34, code);
=======
    
    @Autowired
    private UserMapper userMapper;
    
    @Override
    public String imageCode(String key) {
        
        String code = StrUtils.getComplexRandomString(4);
        redisTemplate.opsForValue().set(key,code,5, TimeUnit.MINUTES);
        
        return VerifyCodeUtils.VerifyCode(100,35,code);
>>>>>>> 815a078707a159f81958d10b606db1f81992e9cf
    }

    @Override
    public void smsCode(RegisterDto dto) {
        String phone = dto.getPhone();
<<<<<<< HEAD
        String type = dto.getType();
        if(StringUtils.isEmpty(phone) || StringUtils.isEmpty(type)){
            throw new BusinessException("参数不能为空！！");
        }
        if(type.equals("register")){
            //走发送注册验证码的逻辑
            sendRegisterSmsCode(dto);

        }else if (type.equals("binder")){
            //发送绑定验证码的逻辑
            sendBinderSmsCode(phone);
        }
    }

    /**
     * 真正的发送验证阿的业务
     */
    private void sendSmsCode(String businessKey){
        //        4.拼接 key register:1598249  去redis中获取，
        String key = businessKey;
        Object smsCodeTmp = redisTemplate.opsForValue().get(key);
        String smsCode = "";
        if(smsCodeTmp != null){
//        4.1 获取到了，说明曾经发过 需要校验是否过了重发时间
            Long oldTime = Long.valueOf(smsCodeTmp.toString().split(":")[1]);
//        。解析value得到上一次的时间戳
//        。用当前系统时间减去上一次时间戳，判断是否小于一分钟  1*60*1000
            if(System.currentTimeMillis() - oldTime <= 1*60*1000){
//        4.1.1 小于一分钟  使劲骂！！！！
                throw new BusinessException("使劲骂！！！！");
            }
//        4.1.2 大于一分钟  使用上次还未过期的9527 ，刷新过期时间为最新，并重新发送
            smsCode = smsCodeTmp.toString().split(":")[0];
        }else{
//        4.2 获取不到 要么就是第一次来，要么是曾经发送的失效了
//        5.生成验证码 code=9527
            smsCode = StrUtils.getComplexRandomString(4);
        }
//        6.存储redis  key register:1598249   value   9527:4697651498456410 设置过期时间为3分钟之后
        String smsCodeValue = smsCode + ":" + System.currentTimeMillis();
        redisTemplate.opsForValue().set(
                key,
                smsCodeValue,//一定要拼接时间戳
                3,
                TimeUnit.MINUTES
        );
//        7.发送短信给手机号1598249
        System.out.println("亲，您的验证码是：" + smsCode + ";请在三分钟内使用！！！");
        //SmsSendUtils.sendSmsMsg(phone,"亲，您的验证码是："+smsCode + ";请在三分钟内使用！！！");
    }

    private void sendBinderSmsCode(String phone) {
        String businessKey = BaseConstants.SmsCodeConstants.BUSINESS_BINDER_PREFIX+phone;
        sendSmsCode(businessKey);
    }

    private void sendRegisterSmsCode(RegisterDto dto) {
        String phone = dto.getPhone();
        String imageCodeKey = dto.getImageCodeKey();
        String imageCodeValue = dto.getImageCodeValue();
//        1.校验
//        。空校验
        if(!StringUtils.hasLength(imageCodeKey)
                || !StringUtils.hasLength(imageCodeValue)
        ){
            throw new BusinessException("参数不能为空！！");
        }
//        2.校验图形验证码
        Object imageCodeTmp = redisTemplate.opsForValue().get(imageCodeKey);
//                imageCode可以从redis查询imageCode
        if(imageCodeTmp == null){
//            。不能查到 直接报错，图形验证已过期，请重新获取
            throw new BusinessException("图形验证码已经失效，请重新获取!");
        }
        if(!imageCodeValue.equalsIgnoreCase(imageCodeTmp.toString())){
//        。能查到 说明图形验证码还没有过期，应该校验imageCodeValue 和 imageCode是否相等 注意：需要忽略大小写校验
//                如果等就报错
            throw new BusinessException("请输入正确的图形验证码!");
        }
//        3.手机号不能被注册
        User userTmp = userMapper.loadByPhone(phone);
        if(userTmp != null){
//        如果被注册，报错：用户已存在，请直接登录！！
            throw new BusinessException("用户已存在，请直接登录！！");
        }

        String businessKey = BaseConstants.SmsCodeConstants.BUSINESS_REGISTER_PREFIX+phone;
        sendSmsCode(businessKey);
=======
        String imageCodeKey = dto.getImageCodeKey();
        String imageCodeValue = dto.getImageCodeValue();
//        1.校验 
//        空校验
        if (!StringUtils.hasLength(phone) 
                || !StringUtils.hasLength(imageCodeKey)
                || !StringUtils.hasLength(imageCodeValue)
        ){
            throw new BusinessException("参数不能为空！");
        }
        // 2.校验图形验证码
        Object imageCodeTmp = redisTemplate.opsForValue().get(imageCodeKey);
        if (imageCodeTmp == null){
            // 没查到，提示用户重新获取
            throw new BusinessException("图形验证码失效，请再次点击获取！");
        }
        if (!imageCodeValue.equalsIgnoreCase(imageCodeTmp.toString())){
            // 查到了，但是需要把imageCodeValue和imageCode进行比较是否相等
            throw new BusinessException("请输入正确的验证码！");
        }
//        3.手机号不能被注册
           User userTmp =  userMapper.loadByPhone(phone);
            if (userTmp != null){
                throw new BusinessException("用户已存在，请登录！");
            }
//        4.拼接key register
        String key = BaseConstants.SmsCodeConstants.BUSINESS_REGISTER_PREFIX + phone;
        Object smsCodeTmp = redisTemplate.opsForValue().get(key);
        String smsCode = "";
        if (smsCodeTmp != null){
            
          Long oldTime = Long.valueOf(smsCodeTmp.toString().split(":")[1]);
          if (System.currentTimeMillis() - oldTime <= 1*60*1000){
              throw new BusinessException("操作太频繁了！");
          }
          smsCode = smsCodeTmp.toString().split(":")[0];
        }else {
             smsCode = StrUtils.getComplexRandomString(4);
        }
        String  smsCodeValue = smsCode + ":" + System.currentTimeMillis();
        redisTemplate.opsForValue().set(
                key,
                smsCodeValue,
                3,
                TimeUnit.MINUTES
        );
        System.out.println("您的验证码是:" + smsCode +"请在三分钟内使用");
//        SmsSendUtils.sendSmsMsg(phone,"您的验证码是:" + smsCode +"请在三分钟内使用");
>>>>>>> 815a078707a159f81958d10b606db1f81992e9cf
    }
    
}